package models

import (
	"strings"
	"time"

	fn "OAM/util"

	"github.com/beego/beego/v2/client/orm"
	"github.com/beego/beego/v2/core/logs"
	jsoniter "github.com/json-iterator/go"
)

const (
	DICT_SYMMETRIC_KEY       = "symmetric_key"
	itemid_os_names          = "os_names"
	itemid_service_softwares = "service_softwares"
)

type DictItem struct {
	ItemId     string `orm:"PK"`
	ItemName   string
	ItemValue  string
	ItemType   string
	UpdateBy   string
	UpdateTime time.Time `orm:"auto_now;type(datetime)"`
}

func GetDictItemById(id string) *DictItem {
	item := DictItem{ItemId: id}
	query := orm.NewOrm()
	err := query.Read(&item)
	if checkQueryErr(err) {
		return nil
	}
	return &item
}

// 读取aes密钥,如果不存在初始化一个
func InitSymmetrickey() string {
	item := DictItem{ItemId: DICT_SYMMETRIC_KEY}
	db := orm.NewOrm()
	err := db.Read(&item)
	if err != nil && err != orm.ErrNoRows {
		panic("读取初始密钥失败")
	}
	var key string
	if err == orm.ErrNoRows || item.ItemValue == "" {
		key = fn.RandomNumStr(32)
		var err1 error
		encryptKey, err1 := fn.RSAEncryptBase64Str(key, "")
		if err1 != nil {
			logs.Error("生成初始密钥失败", err)
			panic("生成初始密钥失败")
		}
		item.ItemValue = encryptKey

		if err == orm.ErrNoRows {
			item.UpdateBy = "sys"
			item.ItemName = "初始密钥"
			_, err1 = db.Insert(&item)
		} else {
			_, err1 = db.Update(&item)
		}

		if err1 != nil {
			logs.Error("初始密钥保存失败", err)
			panic("初始密钥保存失败")
		}
	} else {
		key, err = fn.RSADecryptBase64Str(item.ItemValue, "")
		if err != nil {
			logs.Error("解密初始密钥失败", err)
			panic("解密初始密钥失败")
		}
	}

	return key
}

func SaveDictItem(item DictItem) {
	orm.NewOrm().InsertOrUpdate(item)
	cache().Delete(item.ItemId)
}

//查询默认设置的操作系统名
func GetPresetOS() []string {
	item := getDictCacheFirst(itemid_os_names)
	return strings.Split(item.ItemValue, ",")
}

// 获取预定义的常用软件列表
func GetPresetServiceSoftwares() []AppInfo {
	var apps []AppInfo
	item := getDictCacheFirst(itemid_service_softwares)
	if item.ItemValue != "" {
		err := jsoniter.UnmarshalFromString(item.ItemValue, &apps)
		if err != nil {
			logs.Error("解析预定义软件列表异常:{}", err)
		}
	}
	return apps
}

func getDictCacheFirst(itemId string) DictItem {
	item, err := getCache(itemId)
	if err != nil {
		item = *GetDictItemById(itemId)
		putCache(item)
	}
	return item
}

func cache() fn.MyCache {
	return fn.GetCache(fn.CACHE_DICT)
}

func putCache(item DictItem) {
	cache().Put(item.ItemId, item, time.Minute*60*72)
}

func getCache(itemId string) (DictItem, error) {
	v, err := cache().Get(itemId)
	if err == nil {
		return v.(DictItem), nil
	}
	return DictItem{}, err
}
